import url from "url";
import methods from "methods";
import Layer from "./Layer.js";
import Route from "./route.js";
function Router() {
  const router = function (req, res, next) {
    // 将next 传递给用户
    router.handle(req, res, next);
  };
  router.stack = [];
  router.__proto__ = proto; // 可以找到之前的额方法
  return router;
}
// let router = new Router()
// let router = Router()
const proto = {};
methods.forEach((method) => {
  // router.get('/',function)
  proto[method] = function (path, handlers) {
    // 调用类来管理路径
    let route = new Route();

    handlers = Array.isArray(handlers) ? handlers : [handlers];
    handlers.forEach((handler) => {
      route[method](handler);
    });
    let layer = new Layer(path, route.dispatch.bind(route));
    // 每个路由的层都有一个route属性，对应存放自己的真实路基的
    layer.route = route;
    this.stack.push(layer);
  };
});
proto.use = function (path, ...handlers) {
  if (typeof path === "function") {
    handlers = [path, ...handlers]; // path就是处理函数
    path = "/"; // 如果没写路径就是 / 匹配所有的路径
  }
  handlers.forEach((handler) => {
    const layer = new Layer(path, handler);
    layer.route = undefined; // 中间件没有路由这个对象
    this.stack.push(layer);
  });
};
proto.handle = function (req, res, out) {
  const { pathname, query } = url.parse(req.url, true);
  const method = req.method.toLowerCase();
  let idx = 0;
  let removed = "";
  let next = (err) => {
    if (removed) {
      req.url = removed + req.url;
      removed = "";
    }
    // 如果之前有删除，则在加回来
    if (this.stack.length == idx) return out();
    let layer = this.stack[idx++]; // 拿出第一个层
    if (err) {
      if (!layer.route) {
        // 有错误找中间件，而且 要找参数是4个的中间件
        if (layer.handler.length === 4) {
          layer.handler(err, req, res, next);
        } else {
          next(err); // 普通中间件继续带着错误向下走
        }
      } else {
        // 有错误但是是路由，要带着 错误继续往下走
        next(err);
      }
    } else {
      // 因为错误处理中间件定义在了 router.stack中 ,如果有err就去这个stack中查找错误处理中间件
      if (layer.match(pathname)) {
        // this.params
        console.log(layer.params);
        req.params = layer.params || {};
        if (layer.route) {
          // 路由
          if (layer.route.methods[method]) {
            // 需要匹配方法

            layer.handler(req, res, next); //  route.dispatch
          } else {
            next(); // 方法不一致直接向下走
          }
        } else {
          // 中间件无需匹配方法, 没有错误不能执行错误处理中间件
          if (layer.handler.length !== 4) {
            // 在执行中间件之前，我们需要删除开头

            // /    /user
            if (req.url !== "/") {
              // /user/add    /user
              removed = layer.path;
              // 进入到中间件后  删除中间件的路径
              req.url = req.url.slice(removed.length);
            }
            layer.handler(req, res, next); //  route.dispatch
          } else {
            next();
          }
        }
      } else {
        next();
      }
    }
  };

  next(); // 默认在路由中筛查
};

export default Router;
